import * as path from 'path'
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { RedisModule } from './redis/redis.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { WinstonModule, utilities, WinstonLogger, WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
import * as winston from 'winston'
import { User } from './user/entities/user.entity';
import { Role } from './user/entities/role.entity';
import { Permission } from './user/entities/permission.entity';
import { EmailModule } from './email/email.module';
import { BlogModule } from './blog/blog.module';
import { Blog } from './blog/entities/blog.entity';
import { MinioModule } from './minio/minio.module';
import { UploadModule } from './upload/upload.module';
import { Upload } from './upload/entities/upload.entity';
import { APP_GUARD } from '@nestjs/core';
import { LoginGuard } from './login.guard';
import { PermissionGuard } from './permission.guard';
import { OssModule } from './oss/oss.module';
import { BlogTagModule } from './blog_tag/blog_tag.module';
import { BlogCategoryModule } from './blog_category/blog_category.module';
import { BlogCategory } from './blog_category/entities/blog_category.entity';
import { BlogTag } from './blog_tag/entities/blog_tag.entity';
import { LikeModule } from './like/like.module';
import { StarModule } from './star/star.module';
import { Star } from './star/entities/star.entity';
import { Like } from './like/entities/like.entity';
import { CommentModule } from './comment/comment.module';
import { Comment } from './comment/entities/comment.entity';
import { DailyModule } from './daily/daily.module';
import { Daily } from './daily/entities/daily.entity';
import { CustomTypeOrmLogger } from './CustomTypeOrmLogger';
import { ApisModule } from './apis/apis.module';
import 'winston-daily-rotate-file'
import {ScheduleModule} from '@nestjs/schedule'
import { TaskService } from './task.service';
import { Toutiao } from './apis/entities/toutiao.entity';
import { History } from './apis/entities/history.entity';
// import { EventEmitterModule } from '@nestjs/event-emitter';
import { VisitModule } from './visit/visit.module';
import { VisitCounterMiddleware } from './visit-counter.middleware';
import { Visit } from './visit/entities/visit.entity';
@Module({
  imports: [
  // orm
  TypeOrmModule.forRootAsync({
    useFactory(configService: ConfigService, logger: WinstonLogger) {
      return {
        host: configService.get('mysql_server_host'),
        port: configService.get('mysql_server_port'),
        username: configService.get('mysql_server_username'),
        password:configService.get('mysql_server_password'),
        database: configService.get('mysql_server_database'),
        type: 'mysql',
        connectorPackage: 'mysql2',
        synchronize: true, // 生产环境需要关闭，不然会丢失数据，是否同步更改
        logging: true,
        // logger: new CustomTypeOrmLogger(logger),
        poolSize: 20,
        timezone: "+08:00", // 设置时区
        entities: [User, Role, Permission, Blog, Upload, BlogCategory, BlogTag, Star, Like, Comment, Daily, Toutiao, History, Visit],
        extra: {
          authPlugins: 'sha256_password'
        }
      }
    },
    inject: [ConfigService] // 需要注入configService,
  }),
  // 配置环境变量
  ConfigModule.forRoot({
    isGlobal: true,
    // envFilePath: 'src/.env'
    // 打包后env在dist下面
    envFilePath: path.join(__dirname, '.env')
  }),
  JwtModule.registerAsync({
    global: true,
    async useFactory(configService: ConfigService) {
      return {
        secret: configService.get('jwt_secret'),
        signOptions: {
          expiresIn: configService.get('jwt_expireIn')
        }
      }
    },
    // 需要引进ConfigService
    inject: [ConfigService]
  }),
  // winston日志
  WinstonModule.forRootAsync({
    useFactory: () => ({
      level: 'debug',
      transports: [
        new winston.transports.File({
          filename: `${process.cwd()}/log`,
        }),
        // new winston.transports.DailyRotateFile({
        //   level: 'debug',
        //   dirname: 'daily-log',
        //   filename: 'log-%DATE%.log',
        //   datePattern: 'YYYY-MM-DD',
        //   maxSize: '10k'
        // }),
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp(),
            utilities.format.nestLike(),
          ),
        }),
        // 上传log
        // new winston.transports.Http({
        //   host: 'localhost',
        //   port: 3000,
        //   path: '/log'
        // })
      ],
    }),
    // inject:[WINSTON_MODULE_NEST_PROVIDER]
  }),
  // EventEmitterModule.forRoot(),
  ScheduleModule.forRoot(),
  UserModule,
  RedisModule,
  EmailModule,
  BlogModule,
  MinioModule,
  UploadModule,
  OssModule,
  BlogTagModule,
  BlogCategoryModule,
  LikeModule,
  StarModule,
  CommentModule,
  DailyModule,
  ApisModule,
  VisitModule],
  controllers: [AppController],
  providers: 
  [
    AppService,
    {
      provide: APP_GUARD,
      useClass: LoginGuard
    },
    {
      provide: APP_GUARD,
      useClass: PermissionGuard
    },
    TaskService
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(VisitCounterMiddleware).forRoutes('*');
  }
}
